// the node program that captures local performance data
// and sends it up to the socket.io server
// Req:
// - farmhash
// - socket.io-client
const os = require("os");
const cpus = os.cpus();
const io = require("socket.io-client");
const socket = io("http://127.0.0.1:8181");

socket.on("connect", () => {
  console.log("I connect to the socket server, hooray");
  // we need a way to discern machines
  const nI = os.networkInterfaces();
  let macA;
  // loop thourhg all the nI for this machine and find the non-internal one
  for (let key in nI) {
    if (!nI[key][0].internal) {
      macA = nI[key][0].mac;
      break;
    }
  }

  // client auth with single key value
  socket.emit('clientAuth', 'aljsnfdajnfow')

  let prefDataInterval = setInterval(() => {
    performanceData().then((a) => {
      // console.log(a);
      socket.emit("perfData", allPerformanceData);
    });
  }, 1000);
});

function performanceData() {
  return new Promise(async (resolve, reject) => {
    // what do we need to know from node about performance?
    // - free
    const freemem = os.freemem();
    // console.log(freemem);

    // - total
    const totalmem = os.totalmem();

    // - Memory Usage
    const useMem = totalmem - freemem;
    const memUsage = Math.floor((useMem / totalmem) * 100) / 100;

    // - OS type
    const osType = os.type() == "Darwin" ? "Mac" : os.type();

    // - uptime
    const upTime = os.uptime();

    // - CPU info
    const cpuModel = cpus[0].model;

    // - Number of Cores
    const numCores = cpus.length;

    // - Clock speed: 2600
    const cpuSpeed = cpus[0].speed;

    const cpuLoad = await getCpuLoad();
    resolve({
      freemem,
      totalmem,
      useMem,
      memUsage,
      osType,
      upTime,
      cpuModel,
      numCores,
      cpuSpeed,
      cpuLoad,
    });
  });

  // cpu is all numCores, we need the avg of all cores
  function cpuAvg() {
    const cpus = os.cpus();

    // get ms in each mode, but this number is since reboot
    // so get it now, and get it 100 ms and compare
    let idleMs = 0;
    let totalMs = 0;

    cpus.forEach((aCore) => {
      // loop through each property of the current core
      for (type in aCore.times) {
        totalMs += aCore.times[type];
      }
      idleMs += aCore.times.idle;
    });
    return {
      idle: idleMs / cpus.length,
      total: totalMs / cpus.length,
    };
  }

  // since time property is time since boot, we will get now time and 100ms + and compare them
  // gives us the current load
  function getCpuLoad() {
    return new Promise((resolve, reject) => {
      const start = cpuAvg();
      setTimeout(() => {
        const end = cpuAvg();
        const idleDiff = end.idle - start.idle;
        const totalDiff = end.total - start.total;
        const percCpu = 100 - Math.floor((100 * idleDiff) / totalDiff);
        resolve(percCpu);
      }, 100);
    });
  }
}
